package com.meiyuetao.myt.purchase.entity;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import lab.s2jh.auth.entity.Department;
import lab.s2jh.auth.entity.User;
import lab.s2jh.core.annotation.MetaData;
import lab.s2jh.core.entity.annotation.SkipParamBind;
import lab.s2jh.core.web.json.DateJsonSerializer;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.meiyuetao.myt.core.constant.VoucherStateEnum;
import com.meiyuetao.myt.core.entity.MytBaseEntity;
import com.meiyuetao.myt.finance.entity.AccountSubject;
import com.meiyuetao.myt.stock.entity.CommodityStockMove;

@Entity
@MetaData("采购（收货）单")
@Table(name = "myt_purchase_receipt")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class PurchaseReceipt extends MytBaseEntity {
    private static final long serialVersionUID = 1L;

    @MetaData("供应商")
    private Supplier supplier;

    @MetaData("唯一凭证号")
    private String voucher;
    @MetaData("凭证日期")
    private Date voucherDate;
    @MetaData("凭证状态")
    private VoucherStateEnum voucherState = VoucherStateEnum.DRAFT;
    @MetaData("经办人")
    private User voucherUser;
    @MetaData("经办部门")
    private Department voucherDepartment;

    @MetaData(value = "外部参考来源", comments = "如填写京东网址，淘宝店铺网址等标识采购来源的信息")
    private String externalSource;
    @MetaData(value = "外部参考凭证号", comments = "如京东、淘宝、天猫等订单号等")
    private String externalVoucher;
    @MetaData("备注")
    private String memo;

    private List<PurchaseReceiptDetail> purchaseReceiptDetails = new ArrayList<PurchaseReceiptDetail>();

    /*
     * @MetaData("采购单总税") private BigDecimal totalTaxAmount;
     */

    @MetaData("商品不含税金额")
    private BigDecimal totalCommodityAmount;

    @MetaData("总的商家运费")
    private BigDecimal totalDeliveryAmount;
    @MetaData("总的第三方运费、通关费等")
    private BigDecimal totalRoadAmount;
    @MetaData("采购单总入库价值金额")
    private BigDecimal totalCostAmount;
    @MetaData("已付款金额")
    private BigDecimal payedAmount;

    @MetaData(value = "付款会计科目")
    private AccountSubject accountSubject;
    @MetaData(value = "付款参考信息", comments = "一般用于记录其他三方系统付款的凭证信息")
    private String paymentReference;

    @MetaData(value = "最近操作摘要")
    private String lastOperationSummary;
    @MetaData("红冲时间")
    private Date redwordDate;

    @MetaData(value = "关联采购订单", comments = "限制一个收货单只能最多关联一个采购订单")
    private PurchaseOrder purchaseOrder;

    @MetaData(value = "库存调拨", comments = "限制一个收货单只能最多关联一个库存调拨单")
    private CommodityStockMove commodityStockMove;

    @MetaData("快递公司")
    private Supplier logistics;

    @MetaData("快递单号")
    private String logisticsNo;

    @OneToOne
    @JoinColumn(name = "supplier_SID", nullable = false)
    @JsonProperty
    public Supplier getSupplier() {
        return supplier;
    }

    public void setSupplier(Supplier supplier) {
        this.supplier = supplier;
    }

    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }

    @Column(length = 128, nullable = false, unique = true)
    @JsonProperty
    public String getVoucher() {
        return voucher;
    }

    public void setVoucher(String voucher) {
        this.voucher = voucher;
    }

    @OneToMany(mappedBy = "purchaseReceipt", cascade = CascadeType.ALL, orphanRemoval = true)
    public List<PurchaseReceiptDetail> getPurchaseReceiptDetails() {
        return purchaseReceiptDetails;
    }

    public void setPurchaseReceiptDetails(List<PurchaseReceiptDetail> purchaseReceiptDetails) {
        this.purchaseReceiptDetails = purchaseReceiptDetails;
    }

    @Column(nullable = false)
    @JsonProperty
    @JsonSerialize(using = DateJsonSerializer.class)
    public Date getVoucherDate() {
        return voucherDate;
    }

    public void setVoucherDate(Date voucherDate) {
        this.voucherDate = voucherDate;
    }

    @JsonProperty
    public String getExternalSource() {
        return externalSource;
    }

    public void setExternalSource(String externalSource) {
        this.externalSource = externalSource;
    }

    @JsonProperty
    public String getExternalVoucher() {
        return externalVoucher;
    }

    public void setExternalVoucher(String externalVoucher) {
        this.externalVoucher = externalVoucher;
    }

    /*
     * @Column(precision = 18, scale = 2)
     * 
     * @JsonProperty public BigDecimal getTotalTaxAmount() { return
     * totalTaxAmount; }
     * 
     * public void setTotalTaxAmount(BigDecimal totalTaxAmount) {
     * this.totalTaxAmount = totalTaxAmount; }
     */
    @Column(precision = 18, scale = 2)
    @JsonProperty
    public BigDecimal getTotalCostAmount() {
        return totalCostAmount;
    }

    public void setTotalCostAmount(BigDecimal totalCostAmount) {
        this.totalCostAmount = totalCostAmount;
    }

    @Column(precision = 18, scale = 2)
    @JsonProperty
    public BigDecimal getTotalDeliveryAmount() {
        return totalDeliveryAmount;
    }

    public void setTotalDeliveryAmount(BigDecimal totalDeliveryAmount) {
        this.totalDeliveryAmount = totalDeliveryAmount;
    }

    @Enumerated(EnumType.STRING)
    @Column(length = 8, nullable = true)
    @JsonProperty
    public VoucherStateEnum getVoucherState() {
        return voucherState;
    }

    public void setVoucherState(VoucherStateEnum voucherState) {
        this.voucherState = voucherState;
    }

    @ManyToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "voucher_user_id", nullable = false)
    @JsonProperty
    public User getVoucherUser() {
        return voucherUser;
    }

    public void setVoucherUser(User voucherUser) {
        this.voucherUser = voucherUser;
    }

    @ManyToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "voucher_department_id", nullable = false)
    @JsonProperty
    public Department getVoucherDepartment() {
        return voucherDepartment;
    }

    public void setVoucherDepartment(Department voucherDepartment) {
        this.voucherDepartment = voucherDepartment;
    }

    public BigDecimal getPayedAmount() {
        return payedAmount;
    }

    public void setPayedAmount(BigDecimal payedAmount) {
        this.payedAmount = payedAmount;
    }

    @ManyToOne
    @JoinColumn(name = "account_subject_id")
    public AccountSubject getAccountSubject() {
        return accountSubject;
    }

    public void setAccountSubject(AccountSubject accountSubject) {
        this.accountSubject = accountSubject;
    }

    @Lob
    @JsonIgnore
    public String getPaymentReference() {
        return paymentReference;
    }

    public void setPaymentReference(String paymentReference) {
        this.paymentReference = paymentReference;
    }

    public Date getRedwordDate() {
        return redwordDate;
    }

    @SkipParamBind
    public void setRedwordDate(Date redwordDate) {
        this.redwordDate = redwordDate;
    }

    @JsonProperty
    public String getLastOperationSummary() {
        return lastOperationSummary;
    }

    public void setLastOperationSummary(String lastOperationSummary) {
        this.lastOperationSummary = lastOperationSummary;
    }

    @JsonProperty
    public BigDecimal getTotalCommodityAmount() {
        return totalCommodityAmount;
    }

    public void setTotalCommodityAmount(BigDecimal totalCommodityAmount) {
        this.totalCommodityAmount = totalCommodityAmount;
    }

    public BigDecimal getTotalRoadAmount() {
        return totalRoadAmount;
    }

    public void setTotalRoadAmount(BigDecimal totalRoadAmount) {
        this.totalRoadAmount = totalRoadAmount;
    }

    @ManyToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "purchase_order_sid")
    @JsonProperty
    public PurchaseOrder getPurchaseOrder() {
        return purchaseOrder;
    }

    public void setPurchaseOrder(PurchaseOrder purchaseOrder) {
        this.purchaseOrder = purchaseOrder;
    }

    @ManyToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "commodity_stock_move_sid")
    @JsonProperty
    public CommodityStockMove getCommodityStockMove() {
        return commodityStockMove;
    }

    public void setCommodityStockMove(CommodityStockMove commodityStockMove) {
        this.commodityStockMove = commodityStockMove;
    }

    @OneToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "logistics_sid", nullable = true)
    @JsonProperty
    public Supplier getLogistics() {
        return logistics;
    }

    public void setLogistics(Supplier logistics) {
        this.logistics = logistics;
    }

    @Column(length = 32)
    @JsonProperty
    public String getLogisticsNo() {
        return logisticsNo;
    }

    public void setLogisticsNo(String logisticsNo) {
        this.logisticsNo = logisticsNo;
    }
}
